package jmine.selenium;

import static jmine.selenium.SeleniumMessages.UNABLE_TO_FIND_WAR;
import static jmine.selenium.SeleniumMessages.WEBSERVER_INVALID_URL;
import static jmine.selenium.services.AbstractSeleniumService.SELENIUM_SESSION;
import static jmine.selenium.services.SeleniumApplicationService.APPLICATION_URL;
import static jmine.selenium.services.SeleniumApplicationService.DEFAULT_SESSION;
import static jmine.tec.utils.UtilsMessages.IOEXCEPTION;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;

import jmine.tec.environment.EnvironmentException;
import jmine.tec.utils.io.IOUtils;

/**
 * Classe que tem como objetivo encapsular as configurações de execução de testes de Selenium.
 * 
 * @author Rafael Volpato
 * @date Dec 1, 2010
 */
public final class EnvironmentConfiguration {

    private String webApplicationWARLocation;

    private final URL webApplicationURL;

    private final HashMap<String, Object> globalServiceProperties;

    /**
     * Construtor.
     * 
     * @param webApplicationURL webApplicationURL
     * @param webApplicationWARLocation webApplicationWARLocation
     */
    public EnvironmentConfiguration(String webApplicationURL, String[] webApplicationWARLocation) {
        if (webApplicationWARLocation != null && webApplicationWARLocation.length > 0) {
            for (String warLocation : webApplicationWARLocation) {
                if (new File(warLocation).exists()) {
                    this.webApplicationWARLocation = warLocation;
                    break;
                } else if (this.getClass().getClassLoader().getResource(warLocation) != null) {
                    try {
                        File war =
                                IOUtils.copyToTempFile(warLocation, ".war", this.getClass().getClassLoader().getResource(warLocation)
                                        .openStream());
                        this.webApplicationWARLocation = war.getAbsolutePath();
                        break;
                    } catch (IOException e) {
                        throw new EnvironmentException(IOEXCEPTION.create(), e);
                    }
                }
            }

            if (this.webApplicationWARLocation == null) {
                throw new EnvironmentException(UNABLE_TO_FIND_WAR.create(Arrays.toString(webApplicationWARLocation)));
            }
        }

        try {
            this.webApplicationURL = new URL(webApplicationURL);
        } catch (MalformedURLException e) {
            throw new EnvironmentException(WEBSERVER_INVALID_URL.create(Arrays.toString(webApplicationWARLocation)), e);
        }

        this.globalServiceProperties = new HashMap<String, Object>();
        this.globalServiceProperties.put(APPLICATION_URL, this.webApplicationURL);
        this.globalServiceProperties.put(SELENIUM_SESSION, DEFAULT_SESSION);
    }

    /**
     * Construtor.
     * 
     * @param webApplicationURL webApplicationURL
     */
    public EnvironmentConfiguration(String webApplicationURL) {
        this(webApplicationURL, null);
    }

    /**
     * WAR que deve ser executado dentro do servidor (pode ser <code>null</code>)
     * 
     * @return the webApplicationWARLocation
     */
    public String getWebApplicationWARLocation() {
        return this.webApplicationWARLocation;
    }

    /**
     * @return the webApplicationURL
     */
    public URL getWebApplicationURL() {
        return this.webApplicationURL;
    }

    /**
     * @return the globalServiceProperties
     */
    public HashMap<String, Object> getGlobalServiceProperties() {
        return this.globalServiceProperties;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return String.format("WAR: %s - URL: %s", this.webApplicationWARLocation, this.webApplicationURL);
    }
}
